package datamining.miner.chain;

import java.io.Serializable;
import java.util.Collection;

import datamining.miner.general.Embedding;
import datamining.miner.general.Fragment;
import de.parsemis.miner.general.HPEmbedding;

/**
 * 创建于 2012-11-14 下午10:35:37
 * 
 * @author xujinghu (jinghuxu@nudt.edu.cn)
 * 
 *         版权所有 2012 xujinghu
 * 
 *         许可证 Apache
 */
public abstract class SearchLatticeNode<ItemType> implements Serializable {

	/**
	 * 
	 */
	private static final long serialVersionUID = 1L;

	private int level;

	/*
	 * TODO: perhaps multiple flags like frequent, connected, etc ... or
	 * store it in a fragment ???
	 */
	private boolean store = true;

	protected SearchLatticeNode() {
		this.level = -1;
	}

	protected SearchLatticeNode(final int level) {
		this.level = level;
	}

	/**
	 * @return all embeddings of this node
	 */
	public abstract Collection<Embedding<ItemType>> allEmbeddings();
	
	/**
	 * @param extension
	 * @return a new node resulted by extending this node with the given
	 *         <code>extension</code>
	 */
	public abstract SearchLatticeNode<ItemType> extend(
			Extension<ItemType> extension);

	/**
	 * release all internal structures to the local object pool that are
	 * never needed even if the node is stored
	 */
	public abstract void finalizeIt();

	/**
	 * @return the <code>level</code> (= depth in the search tree) of this
	 *         node
	 */
	public final int getLevel() {
		return level;
	}

	/**
	 * gets the thread index of the SearchLatticeNode
	 * 
	 * @return the thread index
	 */
	public abstract int getThreadNumber();

	/**
	 * release all internal structures to the local object pool that are
	 * never needed if the node is not stored
	 */
	public abstract void release();

	/**
	 * sets the <code>level</code> (= depth in the search tree) of this node
	 * 
	 * @param level
	 */
	public final void setLevel(final int level) {
		this.level = level;
	}

	/**
	 * sets the thread index of the SearchLatticeNode
	 * 
	 * @param threadIdx
	 */
	public abstract void setThreadNumber(int threadIdx);

	/**
	 * @return the set <code>store</code>-value
	 */
	public final boolean store() {
		return store;
	}

	/**
	 * sets the <code>store</code>-value of this node to the given boolean
	 * 
	 * @param store
	 */
	public final void store(final boolean store) {
		this.store = store;
	}
	
	/**
	 * stores the fragment into the given set
	 * 
	 * @param set
	 */
	public void store(final Collection<Fragment> set) {
		set.add(toFragment());
	}
	
	/**
	 * @return the fragment corresponding to this node
	 */
	public abstract Fragment toFragment() ;

}
